/**
* 
* ====================================================================
*
* @author apov <apov@ymail.com>
*/ 
#pragma once

#include <BaseDefine.h>
#include <Thread.h>
#include <queue>
#include <PoplarPool.h>
#include "NetworkSession.h"

#ifdef WIN32

struct Overlapped : public OVERLAPPED{
	int type_;	
};

/**
* @class SessionOverlapped
*  - 
*/
class SessionOverlapped : public NetworkSession{	
	typedef std::queue<LumpData*> SendQ;

	enum{
		DEF_LINGER_TIME=	0, //second
		DEF_BUFFER_COUNT=	10,
	};

public:
	enum{
		DEF_OL_TYPE_NONE=		0,
		DEF_OL_TYPE_RECV=		1,
		DEF_OL_TYPE_SEND=		2,
	};

	virtual bool initialize( Socket socket, bool isBlock = false );	
	virtual int read_handler( int recv_size );
	virtual int write_handler( int write_size = 0 );
	virtual void close_handler(  int type, const char* caller_name = 0 );
	
	virtual int write( char* data, size_t size );
	virtual int write( char* data, size_t size, bool immediate );
	virtual int write( bool lock = true );		
	
	virtual LumpData* getRecvBuffer(){ return (LumpData*)&recv_buffer_; }

	virtual void set_parser_type( size_t parser_type );

	void event_count( int type, bool add );
	void shutdown();

	SessionOverlapped();
	virtual ~SessionOverlapped();

protected:	

private:
	friend class IOCP_IOListener;

	int prepareRead();
	int prepareWrite();

	bool has_event();	
	
	CLock lock_;
	CLock close_lock_;
	CLock event_lock_;	
	
	LumpData recv_buffer_;
	
	LumpData* send_buffer_;	

	Overlapped olRecv_;
	Overlapped olSend_;	
	
	SendQ send_q_;

	int write_event_;
	int read_event_;

	ObjectPool< LumpData > buffers_;
};

#endif